package fr.ul.ade.maquette.ui;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Random;

import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockListFragment;

import fr.ul.ade.maquette.R;
import fr.ul.ade.maquette.ui.util.Bundles;

/**
 * Fragment affichant la liste des cours d'un emploi du temps.
 * 
 * @author Michaël Schnell
 * @since Jun 12, 2013
 * 
 * @version 1.0
 */
public class LessonListFragment
		extends SherlockListFragment {

	OnLessonActionListener mListener;
	long scheduleId;

	/**
	 * Crée une nouvelle instance.
	 * 
	 * @return Instance créée
	 */
	public static LessonListFragment newInstance(long scheduleId) {
		LessonListFragment fragment = new LessonListFragment();
		Bundle args = new Bundle();
		args.putLong(Bundles.SCHEDULE_ID, scheduleId);
		fragment.setArguments(args);
		return fragment;
	}

	/**
	 * Attache l'adaptateur à la liste une fois la vue créée.
	 */
	@Override
	public void onViewCreated(android.view.View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		setListAdapter(new LessonListAdapter(this, this.getArguments()
				.getLong(Bundles.SCHEDULE_ID)));
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);
		// this.mListener = (OnLessonActionListener) this.getActivity();
	}

	/**
	 * Adaptateur utilisée pour la liste. Contient les données codées en dur.
	 */
	static class LessonListAdapter
			extends BaseAdapter {

		LessonListFragment fragment;

		String[] title;
		String[] date;
		String[] startTime;
		String[] endTime;
		String[] room;
		boolean[] change;
		int[] type;

		public LessonListAdapter(LessonListFragment fragment, long scheduleId) {
			this.fragment = fragment;
			this.title = ScheduleData.title[(int) scheduleId];
			this.startTime = ScheduleData.startTime[(int) scheduleId];
			this.endTime = ScheduleData.endTime[(int) scheduleId];
			this.room = ScheduleData.room[(int) scheduleId];
			this.type = ScheduleData.type[(int) scheduleId];
			Random rnd = new Random();
			this.change = new boolean[this.title.length];
			for (int i = 0; i < this.title.length; i++) {
				this.change[i] = rnd.nextBoolean();
			}

			this.date = ScheduleData.date[(int) scheduleId];
			SimpleDateFormat dayParser = new SimpleDateFormat("yyyy/MM/dd");
			SimpleDateFormat dayFormatter = new SimpleDateFormat(
					"EEEE dd MMMM", Locale.FRANCE);
			for (int i = 0; i < this.date.length; ++i) {
				if (this.date[i] != null) {
					try {
						this.date[i] = dayFormatter.format(dayParser
								.parse(this.date[i]));
					} catch (ParseException e) {
						Log.e("[LessonListAdapter]",
								"Invalid date for lesson.",
								e);
					}
				}
			}
		}

		@Override
		public int getCount() {
			return this.title.length;
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public int getItemViewType(int position) {
			return this.type[position];
		}

		@Override
		public int getViewTypeCount() {
			return ItemType.N_LESSON_TYPES;
		}

		/**
		 * Crée une vue pour un item.
		 * 
		 * @param position
		 *            position de l'item concerné
		 * 
		 * @param convertView
		 *            contient une ancienne vue qui peut être recyclée si elle
		 *            n'est pas égale à {@code null}.
		 * 
		 * @param parent
		 *            parent de la vue créée
		 * 
		 * @return vue créée
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			switch (getItemViewType(position)) {
			case ItemType.LESSON:
				return buildLessonItem(position, convertView, parent);

			case ItemType.DATE:
				return buildDateItem(position, convertView, parent);
			default:
			}
			return null;
		}

		/**
		 * @param position
		 * @param convertView
		 * @param parent
		 * @return
		 */
		private View buildDateItem(int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(this.fragment.getActivity())
						.inflate(R.layout.lesson_list_date_item, parent, false);
				final DateViewHolder holder = new DateViewHolder();
				holder.date = (TextView) convertView
						.findViewById(R.id.lesson_list_date);
				convertView.setTag(holder);
			}

			final DateViewHolder holder = (DateViewHolder) convertView.getTag();
			holder.date.setText(this.date[position]);

			return convertView;
		}

		/**
		 * @param position
		 * @param convertView
		 * @param parent
		 * @return
		 */
		private View buildLessonItem(int position, View convertView,
				ViewGroup parent) {
			if (convertView == null) {
				convertView = LayoutInflater.from(this.fragment.getActivity())
						.inflate(R.layout.lesson_list_lesson_item,
								parent,
								false);
				final LessonViewHolder holder = new LessonViewHolder();
				holder.startTime = (TextView) convertView
						.findViewById(R.id.lesson_item_start_time);
				holder.endTime = (TextView) convertView
						.findViewById(R.id.lesson_item_end_time);
				holder.title = (TextView) convertView
						.findViewById(R.id.lesson_item_title);
				holder.room = (TextView) convertView
						.findViewById(R.id.lesson_item_room);
				holder.change = (ImageView) convertView
						.findViewById(R.id.lesson_item_change);
				convertView.setTag(holder);
			}

			final LessonViewHolder holder = (LessonViewHolder) convertView
					.getTag();
			holder.position = position;
			holder.startTime.setText(this.startTime[position]);
			holder.endTime.setText(this.endTime[position]);
			holder.title.setText(this.title[position]);
			holder.room.setText(this.room[position]);
			holder.change.setVisibility(this.change[position] ? View.VISIBLE
					: View.GONE);

			return convertView;
		}

		/**
		 * Active les items pour les rendre clickables.
		 */
		@Override
		public boolean areAllItemsEnabled() {
			return true;
		}

	}

	/**
	 * Classe auxiliaire utilisée pour accéder aux champs d'un item de la liste.
	 * Stocke les résultats des appels à {@link View#findViewById(int)} afin de
	 * de ne devoir rechercher les champs à chaque mise à jour de la vue.
	 * 
	 * @author Michaël Schnell
	 * @since Jun 12, 2013
	 * 
	 * @version 1.0
	 */
	static class LessonViewHolder {
		int position;
		TextView startTime;
		TextView endTime;
		TextView title;
		TextView room;
		ImageView change;
	}

	static class DateViewHolder {
		TextView date;
	}

	interface ItemType {
		public static final int N_LESSON_TYPES = 2;
		public static final int LESSON = 0;
		public static final int DATE = 1;

	}

	public interface OnLessonActionListener {
		public void showLessonDetails(long lessonId);

		public void editSchedule(long scheduleId);

		public void refreshSchedule(long scheduleId);
	}

	interface ScheduleData
			extends ItemType {
		final String[][] title = new String[][] {
				{ null, "SCL", "ARSD", null, "MPR", "SCL", null, "ARSD", "MPR",
						null, "Init. recherche", null, "Parallélisme", null,
						"SCL", "ARSD", null, "MPR", "SCL", null, "ARSD", "MPR",
						null, "Init. recherche", null, "Parallélisme" }, {},
				{}, {} };
		final String[][] date = new String[][] {
				{ "2013/07/01", null, null, "2013/07/02", null, null,
						"2013/07/03", null, null, "2013/07/04", null,
						"2013/07/05", null, "2013/07/08", null, null,
						"2013/07/09", null, null, "2013/07/10", null, null,
						"2013/07/11", null, "2013/07/12", null }, {}, {}, {} };
		final String[][] startTime = new String[][] {
				{ null, "10:00", "14:00", null, "10:00", "14:00", null,
						"10:00", "14:00", null, "14:00", null, "14:00", null,
						"10:00", "14:00", null, "10:00", "14:00", null,
						"10:00", "14:00", null, "14:00", null, "14:00" }, {},
				{}, {} };
		final String[][] endTime = new String[][] {
				{ null, "12:00", "16:00", null, "12:00", "16:00", null,
						"12:00", "16:00", null, "18:00", null, "16:00", null,
						"12:00", "16:00", null, "12:00", "16:00", null,
						"12:00", "16:00", null, "18:00", null, "16:00" }, {},
				{}, {} };
		final String[][] room = new String[][] {
				{ null, "Amphi 01", "315", null, "Amphi 04", "E 31", null,
						"Amphi 16", "319", null, "Aucune salle", null, "310",
						null, "Amphi 01", "315", null, "Amphi 04", "E 31",
						null, "Amphi 16", "319", null, "Aucune salle", null,
						"310" }, {}, {}, {} };
		final int[][] type = new int[][] {
				{ DATE, LESSON, LESSON, DATE, LESSON, LESSON, DATE, LESSON,
						LESSON, DATE, LESSON, DATE, LESSON, DATE, LESSON,
						LESSON, DATE, LESSON, LESSON, DATE, LESSON, LESSON,
						DATE, LESSON, DATE, LESSON }, {}, {}, {} };
	}

}
